package com.quanyan.club.service.impl;

import com.alibaba.fastjson.JSON;
import com.quanyan.api.APIResponse;
import com.quanyan.club.constants.ClubSearchConstants;
import com.quanyan.club.entity.RespClubBaseInfo;
import com.quanyan.club.entity.db.TbActivity;
import com.quanyan.club.entity.db.TbClub;
import com.quanyan.club.entity.db.TbClubMember;
import com.quanyan.club.entity.db.TbClubMemberExample;
import com.quanyan.club.entity.vo.req.ReqClubSearch;
import com.quanyan.club.mapper.TbClubMapper;
import com.quanyan.club.mapper.TbClubMemberMapper;
import com.quanyan.club.service.*;
import com.quanyan.club.thread.ClubSolrIndexThread;
import com.quanyan.club.util.ClubNameUtils;
import com.quanyan.common.Plugin.PageObj;
import com.quanyan.common.constants.Constants;
import com.quanyan.common.utils.DateUtils;
import com.quanyan.common.utils.DistanceUtil;
import com.quanyan.common.utils.StringUtil;
import com.quanyan.common.vo.resp.RespCity;
import com.quanyan.common.vo.resp.RespDistrict;
import com.quanyan.search.entity.request.ReqClubSearchInfo;
import com.quanyan.search.entity.response.ClubSearchResponse;
import com.quanyan.search.entity.response.SearchResponses;
import com.quanyan.search.service.impl.ClubSearchServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.*;

/**
 * Created by zhuo.shi on 2016/11/15.
 *
 * 俱乐部搜索业务服务
 */
@Service
public class ClubSearchBizServiceImpl extends BaseServiceImpl implements ClubSearchBizService {

    private Logger logger = LoggerFactory.getLogger(ClubSearchBizServiceImpl.class);

    @Autowired
    private TbClubMapper clubMapper;
    @Autowired
    private TbClubMemberMapper clubMemberMapper;
    @Autowired
    private ClubMemberService clubMemberService;
    @Autowired
    private ActivitySupportService activitySupportService;
    @Autowired
    private ClubService clubService;
    @Autowired
    private ClubIntegralService clubIntegralService;
    @Autowired
    ThreadPoolTaskExecutor executor;

    private ClubSearchServiceImpl clubSearchService;

    @PostConstruct
    protected  void init(){
        clubSearchService = new ClubSearchServiceImpl(searchCloudUrl);
    }

    /**
     * 俱乐部搜索
     * @param currentUid        当前用户uid
     * @param reqClubSearch     搜索参数
     */
    @Override
    public PageObj<List<RespClubBaseInfo>> searchClubs(Integer currentUid, ReqClubSearch reqClubSearch) {

        ReqClubSearchInfo searchInfo = new ReqClubSearchInfo();
        String keyword = reqClubSearch.getKeyword();
        Integer sortBy = reqClubSearch.getSortBy();

        if (!StringUtil.isBlankOrNull(keyword)){        //关键词，按俱乐部名称、主席昵称搜索
            keyword = keyword.toLowerCase();    //变为小写
            searchInfo.setClub_name(keyword);
            //1 按汉字搜 2 按英文搜 3 按首字母搜 4汉英混合搜
            boolean containsEN = ClubNameUtils.clubNameContainsEN(keyword);
            boolean containsCN = ClubNameUtils.clubNameContainsCN(keyword);

            if (containsCN && !containsEN){     //只包含汉字
                searchInfo.setType((byte)1);
            }
            if (containsEN && !containsCN){     //只包含英文
                searchInfo.setType((byte)2);
            }
            if (containsEN && !containsCN && keyword.length() == 1 && !StringUtils.isNumeric(keyword)){     //只包含英文一个字母
                searchInfo.setType((byte)3);
            }
            if (containsCN && containsEN){      //包含中英文
                searchInfo.setType((byte)4);
            }
            searchInfo.setClub_founder_nickname(keyword);
        }else {     //如果是填入了搜索词，不进行排序
            //排序
            Map<String, String> sortMap = new HashMap<>();
            if (sortBy == null || sortBy == ClubSearchConstants.SORT_BY_DISTANCE){         //默认按距离排序
                sortMap.put("club_dist", "asc");
            }else if (sortBy == ClubSearchConstants.SORT_BY_ACTIVITY_COUNT){               // 按正在报名的活动数量排序
                sortMap.put("club_activity_count", "desc");
            }else if (sortBy == ClubSearchConstants.SORT_BY_STAR){                         // 按评分排序
                sortMap.put("club_star", "desc");
            }
            searchInfo.setSortMap(sortMap);
        }
        //经纬度
        Double lat = reqClubSearch.getLat();
        if (lat != null && lat != 0) {
            searchInfo.setLat(lat);
        }
        Double lng = reqClubSearch.getLng();
        if (lng != null && lng != 0){
            searchInfo.setLng(lng);
        }
        //搜索半径
        if (reqClubSearch.getDistance() != 0){
            searchInfo.setDistance(reqClubSearch.getDistance());
        }

        Integer cityId = reqClubSearch.getCityId();
        if (cityId!= null && cityId != -1) {
            searchInfo.setCity_id(cityId);
        }
//        else {
//            if (lat != null && lng != null) {
//                BaiduLBS baiduLBS = new BaiduLBS();
//                AddressComponent address = baiduLBS.getAddressComponentByLatAndLng(lat, lng);       //根据经纬度获取用户所在城市名
//                String cityName = address.getCity();
//                if(StringUtil.isBlankOrNull(cityName)){
//                    cityId = getCityIdByName(cityName);
//                    searchInfo.setCity_id(cityId);
//                }
//            }
//        }

        Integer districtId = reqClubSearch.getDistrictId();
        if (districtId != null && districtId != -1){
            searchInfo.setDistrict_id(districtId);
        }
        Integer clubTypeId = reqClubSearch.getClubTypeId();
        if (clubTypeId != null && clubTypeId != -1){
            searchInfo.setClub_type_id(clubTypeId);
        }
        searchInfo.setPageNo(reqClubSearch.getPageNo());
        searchInfo.setPageSize(reqClubSearch.getPageSize());
        logger.warn("searchInfo=" + JSON.toJSONString(searchInfo));

        List<RespClubBaseInfo> list = new ArrayList<>();

        if (reqClubSearch.isFirstin()) {
            List<RespClubBaseInfo> myClubs = this.getMyClubs(currentUid, clubTypeId, cityId, districtId, lat, lng);
            list.addAll(myClubs);
        }
        int total = 0;

//        if (StringUtil.isBlankOrNull(keyword) && myClubs.size() != 0 && reqClubSearch.getPageNo() == 0 &&
//                (sortBy != null && sortBy == ClubSearchConstants.SORT_BY_DISTANCE)){
//            list.addAll(myClubs);
//        }

        APIResponse<SearchResponses<List<ClubSearchResponse>>> response = clubSearchService.searchClubInfoListNew(searchInfo);
        logger.warn("searchResult=" + JSON.toJSONString(response));
        if (null ==  response || !response.isRet()) {
            return PageObj.create(total, reqClubSearch.getPageNo(), reqClubSearch.getPageSize(), list);
        }

        SearchResponses<List<ClubSearchResponse>> searchResponse = response.getData();
        if (searchResponse != null) {
            List<ClubSearchResponse> searchResult = searchResponse.getData();
            for (ClubSearchResponse clubSearchResponse : searchResult){
//                if (isDuplicate(clubSearchResponse.getClub_id(), myClubs) && (StringUtil.isBlankOrNull(keyword))){
//                    continue;
//                }
                RespClubBaseInfo clubBaseInfo = convertClubSearch2ClubBaseBean(currentUid, clubSearchResponse);
                list.add(clubBaseInfo);
            }
            total = searchResponse.getTotal();
        }

        return PageObj.create(total, reqClubSearch.getPageNo(), reqClubSearch.getPageSize(), list);
    }

    private boolean isDuplicate(Integer clubId, List<RespClubBaseInfo> myclubs){
        if (clubId == null || myclubs.size() == 0){
            return false;
        }
        for (RespClubBaseInfo baseInfo : myclubs){
            if(baseInfo.getClubId().intValue() == clubId){
                return true;
            }
        }
        return false;
    }

    /**
     * 将搜索返回的实体转化成RespClubBaseInfo
     */
    private RespClubBaseInfo convertClubSearch2ClubBaseBean(Integer currentUid, ClubSearchResponse clubSearchResponse){
        RespClubBaseInfo baseInfo = new RespClubBaseInfo();
        int clubId = clubSearchResponse.getClub_id();
        baseInfo.setClubId(clubId);
        baseInfo.setClubLogo(clubSearchResponse.getClub_logo());
        baseInfo.setClubName(clubSearchResponse.getClub_name());
        baseInfo.setLevel(clubSearchResponse.getClub_level());
        baseInfo.setIntegral(clubSearchResponse.getClub_integral());
        baseInfo.setStar(clubSearchResponse.getClub_star());
        baseInfo.setClubType(clubSearchResponse.getClub_type_id());
        baseInfo.setUsername(clubSearchResponse.getClub_founder_nickname());
        baseInfo.setSportName(clubSearchResponse.getClub_sport_name());
        baseInfo.setDist(clubSearchResponse.getClub_dist());
        RespCity city = new RespCity();
        city.setName(clubSearchResponse.getCity_name());
        baseInfo.setCity(city);
        RespDistrict district = new RespDistrict();
        district.setName(clubSearchResponse.getDistrict());
        baseInfo.setDistrict(district);
        TbClub tbClub = clubMapper.selectByPrimaryKey(clubSearchResponse.getClub_id());         //当前用加入此俱乐部的状态
        if (tbClub != null) {
            baseInfo.setResidentPlaceName(tbClub.getResidentPlaceName());
            baseInfo.setJoinType((int) tbClub.getJoinType());
            if (currentUid != null) {
                baseInfo.setJoin(clubMemberService.isClubMember(currentUid, clubSearchResponse.getClub_id()));
                baseInfo.setStatus(clubMemberService.getJoinClubStatus(clubId, currentUid));
            }
            baseInfo.setPurpose(tbClub.getPurpose());
            baseInfo.setLat(tbClub.getPlaceLat());
            baseInfo.setLng(tbClub.getPlaceLng());
        }
        baseInfo.setRealNameAuth(super.isRealNameAuthClub(clubId));
//        Integer activityCount = clubActivityService.clubActivityListByCondition(clubId);
        Integer activityCount_from_search = clubSearchResponse.getClub_activity_count();
//        logger.warn("俱乐部{}正在报名的人数，db返回={}，搜索返回={}", clubSearchResponse.getClub_id(), activityCount, activityCount_from_search);
        baseInfo.setGoingActivityCount(activityCount_from_search );            //正在报名中的活动场次，索引中从0开始
        baseInfo.setMemberCount(clubMemberService.countClubMembers(clubSearchResponse.getClub_id(), true)); //俱乐部成员人数
        baseInfo.setActivityWeekDays(getActivityWeekDays(clubId));
        return baseInfo;
    }

    /**
     * 获取当前时间往后推移的7天内，此俱乐部可以报名活动的周天数
     */
    @Override
    public List<Integer> getActivityWeekDays(int clubId){
        List<Integer> weekDays = new ArrayList<>();
        List<TbActivity> tbActivities = activitySupportService.activityAfterWeek(clubId);
        if (tbActivities == null || tbActivities.size() == 0){
            return weekDays;
        }
        Map<Date, Integer> dw = new TreeMap<>(new Comparator<Date>() {
            @Override
            public int compare(Date o1, Date o2) {
                return o1.compareTo(o2);
            }
        });
//        List<int[]> daysList = new ArrayList<>();
        for (TbActivity activity : tbActivities){
            Date startTime = activity.getStartTime();
//            if (startTime.before(new Date())){
//                startTime = new Date();
//            }
//            Date endTime = activity.getEndTime();
//            int[] days = new int[7];
//            int i = 0;
//            while (startTime.before(endTime)) {
//                days[i] = DateUtils.getDayOfWeek(startTime);
//                dw.put(startTime, days[i]);
//                startTime = DateUtils.addTime(startTime, 1, DateUtils.TIME_TYPE_DAY);
//                i++;
//            }
//            if (i<7){
//                for (int j = i; j < 7; j++){
//                    days[j] = 0;
//                }
//            }
//            daysList.add(days);
            dw.put(startTime, DateUtils.getDayOfWeek(startTime));
        }
//        System.out.println(dw);
//        int[] weekdays = new int[7];
//        for (int[] wds : daysList){
//            for (int k = 0; k < 7; k++){
//                if (wds[k] != 0){
//                    weekdays[k] = wds[k];
//                }
//            }
//        }
//        for (int w : weekdays){
//            weekDays.add(w);
//        }
        for (Date key: dw.keySet()){
            weekDays.add(dw.get(key));
        }
//        List<Integer> listWithoutDup = new ArrayList<>(new HashSet<>(weekDays));
//        return listWithoutDup;
        return weekDays;
    }

    /**
     * 更新俱乐部正在报名的活动数
     * @param clubId        俱乐部id
     * @param count         活动数， +1给正数，-1给负数
     */
    @Override
    public void updateSignupActivityCountOfClubIndex(int clubId, int count){
        logger.warn("clubId:" + clubId + "count:" + count);
        RespClubBaseInfo clubBaseInfo = clubService.convert2RespClubBaseInfo(null, clubMapper.selectByPrimaryKey(clubId), false);
        int activityCountOfQuery = activitySupportService.countActivityAfterWeek(clubId);
        clubBaseInfo.setGoingActivityCount(activityCountOfQuery);
        double star = clubIntegralService.updateSearchClubStar(clubId);
        clubBaseInfo.setStar(star);
        logger.warn("查询DB中clubId:" + clubId + "，activity count:" + activityCountOfQuery + ", start=" + star);
        //更新索引
        executor.submit(new ClubSolrIndexThread(clubBaseInfo, clubSearchService, true));
    }

    /**
     * 我的俱乐部
     */
    private List<RespClubBaseInfo> getMyClubs(int uid, Integer clubType, Integer cityId, Integer districtId, Double lat, Double lng){
        lat = lat==null?0:lat;
        lng = lng==null?0:lng;

        List<RespClubBaseInfo> resultList = new ArrayList<>();

        TbClubMemberExample example = new TbClubMemberExample();
        example.createCriteria()
                .andUidEqualTo(uid).andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        example.setOrderByClause(" priority");
        List<TbClubMember> tbClubMembers = clubMemberMapper.selectByExample(example);
        if (tbClubMembers == null || tbClubMembers.size() == 0){
            return resultList;
        }
        for (TbClubMember clubMember : tbClubMembers){
            TbClub tbClub = clubMapper.selectByPrimaryKey(clubMember.getClubId());
            if (tbClub == null || tbClub.getIsDelete() == 1){
                continue;
            }
            if (clubType != null && clubType != -1 && tbClub.getClubType().intValue() != clubType){
                continue;
            }
            if (cityId != null && tbClub.getCityId().intValue() != cityId){
                continue;
            }
            if (districtId != null && tbClub.getDistrictId().intValue() != districtId){
                continue;
            }
            RespClubBaseInfo clubBaseInfo = clubService.convert2RespClubBaseInfo(uid, tbClub, false);
            double dist = 0;
            try {
                dist = DistanceUtil.getDistanceRice(tbClub.getPlaceLng(), tbClub.getPlaceLat(), lng, lat);
            }catch (Exception e) {

            }
            clubBaseInfo.setDist(dist);
            clubBaseInfo.setGoingActivityCount(activitySupportService.countActivityAfterWeek(tbClub.getId()));
            resultList.add(clubBaseInfo);
        }

        return resultList;
    }

    @Override
    public void updateClubStarToIndex(int clubId, double star){

        RespClubBaseInfo clubBaseInfo = clubService.convert2RespClubBaseInfo(null, clubMapper.selectByPrimaryKey(clubId), false);
        clubBaseInfo.setStar(star);
        clubBaseInfo.setGoingActivityCount(activitySupportService.countActivityAfterWeek(clubId));
        executor.submit(new ClubSolrIndexThread(clubBaseInfo, clubSearchService, true));
    }
}
